#pragma once

#include "callback.h"
#include "eventloop.h"
#include "acceptor.h"
#include "eventloop_threadpool.h"
#include "inet_address.h"
#include "noncopyable.h"

#include <functional>
#include <string>
#include <memory>
#include <unordered_map>
#include "logger.h"

EventLoop* checkLoopNotNull(EventLoop* loop);

// 对外的服务器编程使用的类
class TcpServer : noncopyable{
public:
    using ThreadInitCallBack = std::function<void(EventLoop*)>;
    enum Option{
        kNoReusePort,             // 端口重用
        kReuserPort,               // 
    };

    TcpServer(EventLoop* loop, const InetAddress& listenAddr,const std::string& nameArg, Option option = kNoReusePort);

    ~TcpServer();

    void setThreadInitCallBack(const ThreadInitCallBack& cb) {threadInitCallBack_ = cb;}
    void setConnectionCallBack(const ConnectionCallBack& cb) {connectionCallBack_ = cb;}
    void setMessageCallBack(const MessageCallBack& cb) {messageCallBack_ = cb;}
    void setWriteCompleteCallBack(const WriteCompleteCallBack& cb) {writeCompleteCallBack_ = cb;}
    // 设置底层的subLoop的个数
    void setThreadNum(int numThreads);
    // 开启服务器监听监听
    void start();

private:
    void newConnection(int sockfd, const InetAddress& peerAddr);
    void removeConnection(const TcpConnectionPtr &conn);
    void removeConnectionInLoop(const TcpConnectionPtr& conn);
    
    using ConnectionMap = std::unordered_map<std::string, TcpConnectionPtr>;

    EventLoop* loop_;               //用户定义的loop
    const std::string ipPort_;
    const std::string name_;
    std::unique_ptr<Acceptor> acceptor_;            // 运行在mainloop, 任务就是监听新连接事件
    std::shared_ptr<EventLoopThreadPool> threadPool_;

    ConnectionCallBack connectionCallBack_;         // 有新连接的回调
    MessageCallBack messageCallBack_;               // 有读写消息是的回调
    WriteCompleteCallBack writeCompleteCallBack_;   // 消息发送完成以后的回调
    ThreadInitCallBack threadInitCallBack_;         // loop线程初始化的回调
    std::atomic_int started_;

    int nextConnId_;
    ConnectionMap connections_;                 // 保存所有连接
};
